package pl.com.ozzy.ozsign.ui;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

import pl.com.ozzy.ozsign.digitalsign.SignatureManager;
import pl.com.ozzy.ozsign.lang.IUIDrawPanelCallback;
import pl.com.ozzy.ozsign.tools.AppConfigManager;
import pl.com.ozzy.ozsign.tools.SignaturesProcessor;
import android.app.Activity;
import android.content.res.Resources;
import android.gesture.Gesture;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

/**
 * This class represents the view of drawing panel.
 * All images of signatures are created right here, 
 * with special SignatureOverlayView control.
 */
public class DrawPanelUI extends Activity implements IUIDrawPanelCallback {
	
	private final static String THIS_FILE = "DrawPanelUI";
	private Gesture mSignature;
    private Button mDoneButton;
    private SignaturesProcessor mSignaturesProcessor;
	
    private int mThumbnailSize;
    private int mThumbnailInset;
    private int mPathColor;
    
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.draw_panel);
        
        Button mDoneButton = (Button)findViewById(R.id.bDone);
        mDoneButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				try {
					addSignature();
				} catch (NoSuchAlgorithmException e) {
					e.printStackTrace();
				} catch (NoSuchProviderException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});
        
        final Resources resources = getResources();
        mPathColor = resources.getColor(R.color.gesture_color);
        mThumbnailInset = (int) resources.getDimension(R.dimen.gesture_thumbnail_inset);
        mThumbnailSize = (int) resources.getDimension(R.dimen.gesture_thumbnail_size);
        
        mSignaturesProcessor = new SignaturesProcessor(mSignature, this);
        GestureOverlayView overlay = (GestureOverlayView) findViewById(R.id.gestureOverlay);
        overlay.addOnGestureListener(mSignaturesProcessor);
    }
    
    /*
     * (non-Javadoc)
     * @see android.app.Activity#onSaveInstanceState(android.os.Bundle)
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        
        if (mSignature != null) {
            outState.putParcelable("gesture", mSignature);
        }
    }

    /*
     * (non-Javadoc)
     * @see android.app.Activity#onRestoreInstanceState(android.os.Bundle)
     */
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        
        mSignature = savedInstanceState.getParcelable("gesture");
        if (mSignature != null) {
            final GestureOverlayView overlay =
                    (GestureOverlayView) findViewById(R.id.gestureOverlay);
            overlay.post(new Runnable() {
                public void run() {
                    overlay.setGesture(mSignature);
                }
            });

            mDoneButton.setEnabled(true);
        }
    }
    
    /*
     * Adds getsture to gestures library.
     */
    private void addSignature() throws NoSuchAlgorithmException, NoSuchProviderException, IOException {
    	if (mSignaturesProcessor != null) {
    		mSignature = mSignaturesProcessor.getGesture();
	        if (mSignature != null) {
	            final TextView input = (TextView) findViewById(R.id.etGestureName);
	            final CharSequence name = input.getText();
	            if (name.length() == 0) {
	                input.setError(getString(R.string.msg_error_missing_name));
	                Log.d(THIS_FILE, "Empty name for new signature");
	                return;
	            }
	
	            final GestureLibrary store = AppConfigManager.gStore;
	            store.addGesture(name.toString(), mSignature);
	            store.save();
	            
	            /*
	             * Create key pair with names based on signature image hash 
	             */
	            SignatureManager mSigManager = new SignatureManager();
	            MessageDigest mDigest = MessageDigest.getInstance("MD5");
	            Bitmap mBitmap = mSignature.toBitmap(mThumbnailSize, mThumbnailSize,
                        mThumbnailInset, mPathColor);
	            
	            /*
	             * Get Bitmap object as byte array
	             */
	            ByteArrayOutputStream mBos = new ByteArrayOutputStream(); 
	            mBitmap.compress(CompressFormat.PNG, 0, mBos); 
	            byte[] digestBuf = mBos.toByteArray();
	            
	            /*
	             * Create MD5 hash 
	             */
	            mDigest.update(digestBuf);
	            digestBuf = mDigest.digest(digestBuf);
	            StringBuffer hexString = new StringBuffer();

	            /*
	             * Rewrite hash to hex string
	             */
	            for (int i=0; i<digestBuf.length; i++) {
	                hexString.append(Integer.toHexString(0xFF & digestBuf[i]));
	            }
	            String mName = new String(hexString);
	            
	            /*
	             * Create and save keys
	             */
	            mSigManager.createKeyPair(mName, mName.concat("_pub"));
	            
	            /*
	             * Set activity result and show toast
	             */
	            setResult(AppConfigManager.STATUS_GESTURE_ADDED);
	
	            final String path = new File(Environment.getExternalStorageDirectory(),
	                    "gestures").getAbsolutePath();
	            Toast.makeText(this, getString(R.string.msg_save_success, path), Toast.LENGTH_LONG).show();
	        } else {
	        	Log.d(THIS_FILE, "Signature cancelled");
	            setResult(RESULT_CANCELED);
	        }
    	} else {
    		Log.e(THIS_FILE, "No gesture processor set for SignatureOverlay");
    	}

        finish();
        
    }

	@Override
	public void executeOnStarted() {
		/*
		 * Disable UI elements
		 */
		if (mDoneButton == null) {
        	mDoneButton = (Button)findViewById(R.id.bDone);
        }
		mDoneButton.setEnabled(false);
	}

	@Override
	public void executeOnEnded() {
		/*
		 * Enable UI elements
		 */
		if (mDoneButton == null) {
        	mDoneButton = (Button)findViewById(R.id.bDone);
        }
		 mDoneButton.setEnabled(true);		
	}
}
